package co.edu.eam.iso.chart;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.text.NumberFormat;
import java.util.Map;
import java.util.Map.Entry;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.TextAnchor;

import co.edu.eam.iso.chart.model.ChartData;

/**
 * @author Giovanny Ramirez
 */
public class CharGenerator {
	
	private static CharGenerator instance;
	
	public ChartPanel generateChart(
			Map<String, Map<String, ChartData>> chartData, char optionSelected,
			boolean showWeight) {
		CategoryDataset dataset = createDataset(chartData, optionSelected, showWeight);
		JFreeChart chart = createChart(dataset, chartData, optionSelected, showWeight);
		
		ChartPanel chartPanel = new ChartPanel(chart);
		chartPanel.setFillZoomRectangle(true);
		chartPanel.setMouseWheelEnabled(true);
		chartPanel.setPreferredSize(new Dimension(500, 270));

		return chartPanel;
	}
	
	private CategoryDataset createDataset(
			Map<String, Map<String, ChartData>> chartData, char optionSelected,
			boolean showWeight) {
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		
		for (Entry<String, Map<String, ChartData>> productsEvaluation : chartData.entrySet()) {
			String productName = productsEvaluation.getKey();
			
			for (Entry<String, ChartData> productEvaluation : productsEvaluation.getValue().entrySet()) {
				String key = productEvaluation.getKey();
				ChartData evaluationData = productEvaluation.getValue();
				
				if (optionSelected == 'T') {
					double quality = evaluationData.averageTotalQuality();
					dataset.addValue(quality, productName, productName);
					
				} else {
					if (showWeight) {
						double quality = optionSelected == 'C' ? evaluationData
								.averageQualityVStotal() : evaluationData.averageQuality();
						
						dataset.addValue(quality, key, productName);
						dataset.addValue(evaluationData.averageWeight(), "V. " + key, productName);
					} else {
						dataset.addValue(evaluationData.averageQuality(), key, productName);
					}
				}
			}
		}
 		
		return dataset;
	}
	
	private JFreeChart createChart(CategoryDataset dataset,
			Map<String, Map<String, ChartData>> chartData, char optionSelected,
			boolean showWeight) {
		String buffer = "";
		int count = 0;
		for (String productName : chartData.keySet()) {
			count++;
			
			if (count == chartData.keySet().size()) {
				buffer += productName;
			} else {
				buffer += productName + " VS ";
			}
		}
		
		String title = "Calidad del producto: " + buffer;
		buffer = "";
		
		if (chartData.keySet().size() > 1) {
			buffer += "Comparación del ";
		}
		
		if (optionSelected == 'T') {
			buffer += "% de calidad total de los productos evaluados ";
		} else if (optionSelected == 'C') {
			buffer += "% de calidad de las características evaluadas ";
		} else if (optionSelected == 'S') {
			buffer += "% de calidad de las subcaracterísticas evaluadas ";
		}
		
		if (showWeight) {
			buffer += "VS Valor seleccionado en la evaluación";
		}
		
		String subtitle = buffer;
		
		JFreeChart chart = ChartFactory.createBarChart(title, null,
				"Calidad (%)", dataset);
		
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        CategoryItemLabelGenerator generator = new StandardCategoryItemLabelGenerator("{0}", NumberFormat.getInstance());
        
        CategoryItemRenderer itemRenderer = plot.getRenderer();
        itemRenderer.setBaseItemLabelGenerator(generator);
        itemRenderer.setBaseItemLabelFont(new Font("SansSerif", Font.PLAIN, 12));
        itemRenderer.setBaseItemLabelsVisible(true);
		itemRenderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(
				ItemLabelAnchor.CENTER, TextAnchor.CENTER, TextAnchor.CENTER, -Math.PI / 2));

		chart.addSubtitle(new TextTitle(subtitle));
		chart.setBackgroundPaint(Color.white);

		// ******************************************************************
		// More than 150 demo applications are included with the JFreeChart
		// Developer Guide...for more information, see:
		//
		// > http://www.object-refinery.com/jfreechart/guide.html
		//
		// ******************************************************************

		NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		BarRenderer barRenderer = (BarRenderer) plot.getRenderer();
		barRenderer.setDrawBarOutline(false);
		barRenderer.setMaximumBarWidth(0.20);
		chart.getLegend().setFrame(BlockBorder.NONE);
		return chart;
	}

	public static CharGenerator getInstance() {
		if (instance == null) {
			instance = new CharGenerator();
		}
		return instance;
	}

}
